{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# CIFAR10 Image Classification Using TensorFlow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pickle\n",
    "import tensorflow as tf\n",
    "from tqdm import tqdm\n",
    "import sys\n",
    "import os\n",
    "import cv2\n",
    "from time import time"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第一章 CIFAR10 上手"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. CIFAR10 数据集概述\n",
    "\n",
    "- 总计 60000 张图片。其中 50000 张用于训练，10000 张用于测试。\n",
    "- 所有图片的尺寸统一为 32 x 32 x 3\n",
    "- 图片的内容标签分为 10 类，每张图片的标签唯一。\n",
    "- 每一类图片的个数都是 6000 张。 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. CIFAR10 数据集分析\n",
    "\n",
    "- 图片尺寸全部统一，因此无需对图片尺寸进行 resize。\n",
    "- 每一个标签的数据量相等，因此整个数据集是平衡的（Balanced），不存在非平衡数据集的训练问题。\n",
    "- 数据集很庞大，有六万张照片，不存在小数据集训练的过拟合问题。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. CIFAR10 数据集格式\n",
    "\n",
    "- 压缩包里含有 6 个 Pickle 文件，其中 5 个 `data_batch` 是训练集，单独一个 `test_batch` 是测试集。\n",
    "- 用 `pickle.load()` 将所有文件中的数据都读入内存\n",
    "\n",
    "\n",
    "- 每个 Pickle 文件都含有 10000 张图片及其展示的内容标签。Pickle 文件所包含的对象是一个词典，该词典有如下4个键：\n",
    "    - data：图像像素数据，np.array 类型\n",
    "    - labels：图像内容标签，list 类型\n",
    "    - filenames：原始图像的文件名（目前用不上）\n",
    "    - batch_label：数据所属的训练集编号（没什么用）\n",
    "    \n",
    "    \n",
    "- data 是一个尺寸为 (10000, 3072) 的 Numpy 数组\n",
    "    - 每一行是一张图片的所有像素，长度为3072\n",
    "    - 每张图片的尺寸是32x32=1024，其三个颜色通道串联接在一起，即 1024,1024,1024\n",
    "    - 需要将每张尺寸为 (1, 3072) 的图片还原为正常的图像尺寸 (32, 32, 3)\n",
    "    - 由于考虑到目前第一维只能是颜色通道，因此应该先将其 reshape(3, 32, 32), 再用 transpose 把颜色通道交换至最后一个维度。\n",
    "    \n",
    "\n",
    "- labels 是一个长度为 10000 的 list，表示图像的实际内容类别，取值为 [0, 9]，其涵义如下：\n",
    "    - 0 = airplane\t\t\t\t\t\t\t\t\t\t\n",
    "    - 1 = automobile\t\t\t\t\t\t\t\t\t\t\n",
    "    - 2 = bird\t\t\t\t\t\t\t\t\t\t\n",
    "    - 3 = cat\t\t\t\t\t\t\t\t\t\t\n",
    "    - 4 = deer\t\t\t\t\t\t\t\t\t\t\n",
    "    - 5 = dog\t\t\t\t\t\t\t\t\t\t\n",
    "    - 6 = frog\t\t\t\t\t\t\t\t\t\t\n",
    "    - 7 = horse\t\t\t\t\t\t\t\t\t\t\n",
    "    - 8 = ship\t\t\t\t\t\t\t\t\t\t\n",
    "    - 9 = truck"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "path = 'cifar-10-batches-py//'\n",
    "p = pickle.load(open(path + 'data_batch_1', 'rb'), encoding='bytes')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys([b'data', b'labels', b'filenames', b'batch_label'])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, list)"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = p[b'data']\n",
    "labels = p[b'labels']\n",
    "type(data), type(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((10000, 3072), 10000)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape, len(lables)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nD9l1pU8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2baed5de7b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(32, 32, 3)"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 看第一张图片的样子\n",
    "pic = np.random.choice(range(10000))\n",
    "img = data[pic].reshape(3, 32, 32)    # 先以颜色通道为大，分离出三个颜色通道\n",
    "img = np.transpose(img, (1, 2, 0))    # 然后将颜色通道维度从原来的第0维换至最后一维\n",
    "plt.imshow(img, cmap='gray')\n",
    "plt.show()\n",
    "img.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. CIFAR10 数据集预处理\n",
    "\n",
    "- 合并全部 50000 张训练图片及其标签\n",
    "- 将像素灰度值归一化\n",
    "- 将标签进行 One-Hot 编码，以供后期使用 Softmax 进行预测\n",
    "- 导出经过预处理后的训练数据为 Pickle 文件，方便以后直接调用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 合并全部 50000 张训练图片及其标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 先申请一块完整的内存，然后再用循环慢慢将这块内存填满，这样比不断追加的方案内存效率高得多\n",
    "X = np.zeros((50000, 32, 32, 3), dtype=np.uint8)\n",
    "Y = []\n",
    "path = 'cifar-10-batches-py//'\n",
    "\n",
    "for i in range(1, 6):\n",
    "    p = pickle.load(open(path + 'data_batch_' + str(i), 'rb'), encoding='bytes')\n",
    "    data = p[b'data']\n",
    "    labels = p[b'labels']\n",
    "    data = data.reshape(10000, 3, 32, 32)\n",
    "    data = np.transpose(data, (0, 2, 3, 1))\n",
    "    \n",
    "    # Append data\n",
    "    X[(i - 1) * 10000 : i * 10000] = data\n",
    "    \n",
    "    # Concat labels\n",
    "    Y += labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((50000, 32, 32, 3), 50000)"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape, len(Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2baed474be0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Check a random img and it's label\n",
    "mapping = {0:'airplane', \n",
    "           1:'automobile', \n",
    "           2:'bird', \n",
    "           3:'cat', \n",
    "           4:'deer', \n",
    "           5:'dog', \n",
    "           6:'frog', \n",
    "           7:'horse', \n",
    "           8:'ship', \n",
    "           9:'truck'}\n",
    "rid = np.random.choice(range(50000))\n",
    "img = X_norm[rid]\n",
    "l = Y[rid]\n",
    "plt.imshow(img, cmap='gray')\n",
    "plt.title(mapping[l])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 对像素灰度值进行归一化\n",
    "\n",
    "在训练模型之前，我们通常都要把图像数据（像素点灰度值）归一化到一个较小的取值范围。这么做的根本原因来自于激活函数，像 Sigmoid 和 Tanh 这样的激活函数在输入较大或较小值时的梯度会变为0，因此模型无法收敛、无法学习，你将看到模型的准确率始终停留在瞎猜阶段。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X_norm = (X - np.min(X)) / (np.max(X) - np.min(X))\n",
    "X_norm = X_norm.astype(np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 59,  43,  50,  68,  98],\n",
       "       [ 16,   0,  18,  51,  88],\n",
       "       [ 25,  16,  49,  83, 110],\n",
       "       [ 33,  38,  87, 106, 115],\n",
       "       [ 50,  59, 102, 127, 124]], dtype=uint8)"
      ]
     },
     "execution_count": 184,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对比归一化后同一张图片相同区域像素点的取值变化\n",
    "X[0, :5, :5, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.23137255,  0.16862746,  0.19607843,  0.26666668,  0.38431373],\n",
       "       [ 0.0627451 ,  0.        ,  0.07058824,  0.2       ,  0.34509805],\n",
       "       [ 0.09803922,  0.0627451 ,  0.19215687,  0.32549021,  0.43137255],\n",
       "       [ 0.12941177,  0.14901961,  0.34117648,  0.41568628,  0.4509804 ],\n",
       "       [ 0.19607843,  0.23137255,  0.40000001,  0.49803922,  0.48627451]], dtype=float32)"
      ]
     },
     "execution_count": 192,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_norm[0, :5, :5, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(146.48451232910156, 585.9376373291016)"
      ]
     },
     "execution_count": 193,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 由于元素类型从 uint8 变成 float32，因此占用空间增大很多\n",
    "sys.getsizeof(X)/1024/1024, sys.getsizeof(X_norm)/1024/1024"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 对标签进行 One-Hot 编码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import LabelBinarizer\n",
    "lb = LabelBinarizer()\n",
    "# 按照数字顺序进行映射，如果直接 fit_transform 的话映射顺序取决于样本中类型的出现顺序\n",
    "lb.fit(range(10)) \n",
    "Y_onehot = lb.transform(Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, (50000, 10), 6, array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0]))"
      ]
     },
     "execution_count": 172,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(Y_onehot), Y_onehot.shape, Y[0], Y_onehot[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.4 导出预处理后的训练数据\n",
    "\n",
    "- 将训练数据输出为含有 4 个元素的 Tuple\n",
    "    - 前两个是训练集图像及其标签，含有 45000 张图片\n",
    "    - 后两个是验证集图像及其标签，含有 5000  张图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "pickle.dump((X_norm[:45000], Y_onehot[:45000], \n",
    "             X_norm[45000:], Y_onehot[45000:],), \n",
    "            open('CIFAR10 Preprocessed', 'wb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第二章 CIFAR10 模型训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 载入预处理后的训练数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_train Dimension:  (45000, 32, 32, 3)\n",
      "Y_train Dimension (45000, 10)\n",
      "X_test Dimension:  (5000, 32, 32, 3)\n",
      "Y_test Dimension (5000, 10)\n"
     ]
    }
   ],
   "source": [
    "X_train, Y_train, X_test, Y_test = pickle.load(open('CIFAR10 Preprocessed', mode='rb'))\n",
    "print(\"X_train Dimension: \", X_train.shape)\n",
    "print(\"Y_train Dimension\", Y_train.shape)\n",
    "print(\"X_test Dimension: \", X_test.shape)\n",
    "print(\"Y_test Dimension\", Y_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 计算卷积层的输出尺寸\n",
    "\n",
    "- 卷积层输出的矩阵尺寸由三个因素决定：\n",
    "    - 输入矩阵尺寸\n",
    "    - 卷积核尺寸\n",
    "    - 步长\n",
    "    \n",
    "\n",
    "- 计算公式为\n",
    "\n",
    "$$\\mathrm{output = (input - kernel + 2 * padding) ~ / ~ stride + 1}$$\n",
    "\n",
    "下面用指针的思路写了一个推测输出形状的函数，比计算公式好理解。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Input Shape =  (32, 32, 3)\n",
      "Output Shape =  (15, 15, 64)\n"
     ]
    }
   ],
   "source": [
    "# 假设输入图片和卷积核的形状都是正方形\n",
    "def get_output_shape(input_shape, kernel_shape, stride):\n",
    "    j = kernel_shape - 1\n",
    "    c = 0\n",
    "    while j < input_shape:\n",
    "        c += 1\n",
    "        j += stride\n",
    "    return c\n",
    "\n",
    "# 假设图片尺寸为 32 x 32 x 3，卷积核尺寸为 3 x 3 x 3，步长为 2，卷积核个数 64\n",
    "n_kernel = 64\n",
    "input_shape = 32\n",
    "output_shape = get_output_shape(32, 3, 2)\n",
    "print('Input Shape = ', (input_shape, input_shape, 3))\n",
    "print('Output Shape = ', (output_shape, output_shape, n_kernel))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 构造模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 模型由以下几层组合而成\n",
    "    - **卷积层**：用卷积核与每个图像进行卷积计算，输出特征图（Feature map），图像的深度得到扩展。\n",
    "    - **池化层**：挑选取值最大的像素点作为代表，主要意义是降维（降低图像尺寸）\n",
    "    - **展开层**：将三维的图像数据拉直为一维向量，向量的每个元素被视为一个特征，方便送入全连接层。\n",
    "    - **全连接层**：特征的非线性分类器，与 MLP 中的全链接层功能一样。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### tf.layers.conv2d\n",
    "> tf.layers.conv2d(inputs, filters, kernel_size, strides=(1, 1), padding='valid', data_format='channels_last', dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer=None, bias_initializer=?, kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, trainable=True, name=None, reuse=None)\n",
    "\n",
    "### tf.nn.conv2d\n",
    "\n",
    "> tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)\n",
    "\n",
    "conv2d 是一个 operation，要求输入的 input 和 filter 本身都是 Tensor 类型的对象，因此需要先用 `tf.Variable` 定义这两个对象，并且对权重矩阵这个 Tensor 进行初始化才能调用 conv2d 函数。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def conv_layer(x, out_channel, k_size, stride, padding):\n",
    "    in_channel = x.shape[3].value\n",
    "    w = tf.Variable(tf.truncated_normal([k_size, k_size, in_channel, out_channel], mean=0, stddev=stddev))\n",
    "    b = tf.Variable(tf.zeros(out_channel))\n",
    "    x = tf.nn.conv2d(x, filter=w, strides=[1, stride, stride, 1], padding=padding)\n",
    "    x = tf.nn.bias_add(x, b)\n",
    "    x = tf.nn.relu(x)\n",
    "    return x\n",
    "\n",
    "\n",
    "def pool_layer(x, k_size, stride, padding):\n",
    "    return tf.nn.max_pool(x, ksize=[1, k_size, k_size, 1], strides=[1, stride, stride, 1], padding=padding)\n",
    "\n",
    "\n",
    "def flatten_layer(x):\n",
    "    dim = x.shape[1].value * x.shape[2].value * x.shape[3].value\n",
    "    return tf.reshape(x, shape=[-1, dim])\n",
    "\n",
    "\n",
    "def fc_layer(x, n_output):\n",
    "    w = tf.Variable(tf.truncated_normal([x.shape[1].value, n_output], mean=0, stddev=stddev))\n",
    "    b = tf.Variable(tf.zeros(n_output))\n",
    "    x = tf.matmul(x, w)\n",
    "    x = tf.add(x, b)\n",
    "    x = tf.nn.relu(x)\n",
    "    return x\n",
    "\n",
    "\n",
    "def dropout_layer(x, keep_prob):\n",
    "    return tf.nn.dropout(x, keep_prob)\n",
    "\n",
    "\n",
    "def output_layer(x, n_output):\n",
    "    w = tf.Variable(tf.truncated_normal([x.shape[1].value, n_output], mean=0, stddev=stddev))\n",
    "    b = tf.Variable(tf.zeros(n_output))\n",
    "    x = tf.matmul(x, w)\n",
    "    x = tf.add(x, b)\n",
    "    x = tf.identity(x, name='logits')  # Rename\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def create_model(x, keep_prob):\n",
    "    x = conv_layer(x, 16, 3, 1, 'SAME')\n",
    "    x = pool_layer(x, 2, 2, 'VALID')\n",
    "    x = conv_layer(x, 32, 3, 1, 'SAME')\n",
    "    x = pool_layer(x, 2, 2, 'VALID')\n",
    "    x = conv_layer(x, 64, 3, 1, 'SAME')\n",
    "    x = pool_layer(x, 2, 2, 'VALID')\n",
    "    x = flatten_layer(x)\n",
    "    x = fc_layer(x, 128)\n",
    "    x = dropout_layer(x, keep_prob)\n",
    "    x = output_layer(x, 10)   \n",
    "    return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 训练模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 建立计算图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "epoch = 100\n",
    "n_class = 10\n",
    "batch_size = 256\n",
    "stddev = 0.01\n",
    "dropout = 0.5\n",
    "\n",
    "tf.reset_default_graph()\n",
    "x_input   = tf.placeholder(tf.float32, shape=(None, 32, 32, 3), name='x_input')\n",
    "y_true    = tf.placeholder(tf.float32, shape=(None, n_class), name='y_true')\n",
    "keep_prob = tf.placeholder(tf.float32, name='keep_prob')\n",
    "\n",
    "y_pred = create_model(x_input, keep_prob)\n",
    "cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_pred, labels=y_true))\n",
    "optimizer = tf.train.AdamOptimizer().minimize(cost)\n",
    "correct_pred = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_true, 1))    \n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name='accuracy')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 数据生成器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_batch(x, y, batch_size):\n",
    "    for start in range(0, len(x), batch_size):\n",
    "        end = min(start + batch_size, len(x))\n",
    "        yield x[start:end], y[start:end]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 用 Session 执行运算图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch = 0     train_loss = 1.98898      train_acc = 25.0 %      validation_acc = 27.42 %\n",
      "Epoch = 1     train_loss = 1.80629      train_acc = 33.5 %      validation_acc = 34.16 %\n",
      "Epoch = 2     train_loss = 1.67055      train_acc = 41.5 %      validation_acc = 37.08 %\n",
      "Epoch = 3     train_loss = 1.61715      train_acc = 43.5 %      validation_acc = 38.92 %\n",
      "Epoch = 4     train_loss = 1.5671      train_acc = 43.0 %      validation_acc = 40.76 %\n",
      "Epoch = 5     train_loss = 1.51051      train_acc = 45.0 %      validation_acc = 42.7 %\n",
      "Epoch = 6     train_loss = 1.49546      train_acc = 43.5 %      validation_acc = 44.52 %\n",
      "Epoch = 7     train_loss = 1.47247      train_acc = 45.5 %      validation_acc = 45.62 %\n",
      "Epoch = 8     train_loss = 1.43555      train_acc = 47.5 %      validation_acc = 47.2 %\n",
      "Epoch = 9     train_loss = 1.40665      train_acc = 49.5 %      validation_acc = 48.76 %\n",
      "Epoch = 10     train_loss = 1.38492      train_acc = 49.5 %      validation_acc = 50.28 %\n",
      "Epoch = 11     train_loss = 1.3654      train_acc = 52.0 %      validation_acc = 50.66 %\n",
      "Epoch = 12     train_loss = 1.34807      train_acc = 50.5 %      validation_acc = 51.4 %\n",
      "Epoch = 13     train_loss = 1.3255      train_acc = 51.5 %      validation_acc = 52.8 %\n",
      "Epoch = 14     train_loss = 1.29893      train_acc = 54.5 %      validation_acc = 53.16 %\n",
      "Epoch = 15     train_loss = 1.28637      train_acc = 54.0 %      validation_acc = 54.7 %\n",
      "Epoch = 16     train_loss = 1.27514      train_acc = 54.0 %      validation_acc = 55.4 %\n",
      "Epoch = 17     train_loss = 1.26014      train_acc = 55.0 %      validation_acc = 55.62 %\n",
      "Epoch = 18     train_loss = 1.22133      train_acc = 54.5 %      validation_acc = 56.92 %\n",
      "Epoch = 19     train_loss = 1.20548      train_acc = 56.0 %      validation_acc = 57.18 %\n",
      "Epoch = 20     train_loss = 1.21909      train_acc = 55.0 %      validation_acc = 57.72 %\n",
      "Epoch = 21     train_loss = 1.17616      train_acc = 56.5 %      validation_acc = 58.88 %\n",
      "Epoch = 22     train_loss = 1.16579      train_acc = 56.5 %      validation_acc = 59.64 %\n",
      "Epoch = 23     train_loss = 1.14341      train_acc = 59.5 %      validation_acc = 59.96 %\n",
      "Epoch = 24     train_loss = 1.11902      train_acc = 57.5 %      validation_acc = 61.16 %\n",
      "Epoch = 25     train_loss = 1.11221      train_acc = 58.5 %      validation_acc = 60.32 %\n",
      "Epoch = 26     train_loss = 1.08903      train_acc = 58.5 %      validation_acc = 62.08 %\n",
      "Epoch = 27     train_loss = 1.07181      train_acc = 62.0 %      validation_acc = 62.18 %\n",
      "Epoch = 28     train_loss = 1.06336      train_acc = 63.0 %      validation_acc = 62.68 %\n",
      "Epoch = 29     train_loss = 1.0607      train_acc = 63.5 %      validation_acc = 62.08 %\n",
      "Epoch = 30     train_loss = 1.04084      train_acc = 62.0 %      validation_acc = 63.82 %\n",
      "Epoch = 31     train_loss = 1.01919      train_acc = 61.0 %      validation_acc = 63.14 %\n",
      "Epoch = 32     train_loss = 0.996471      train_acc = 62.5 %      validation_acc = 64.42 %\n",
      "Epoch = 33     train_loss = 0.982946      train_acc = 65.5 %      validation_acc = 64.68 %\n",
      "Epoch = 34     train_loss = 0.960831      train_acc = 66.5 %      validation_acc = 64.48 %\n",
      "Epoch = 35     train_loss = 0.963135      train_acc = 65.0 %      validation_acc = 66.2 %\n",
      "Epoch = 36     train_loss = 0.937777      train_acc = 67.0 %      validation_acc = 65.6 %\n",
      "Epoch = 37     train_loss = 0.912769      train_acc = 67.0 %      validation_acc = 65.84 %\n",
      "Epoch = 38     train_loss = 0.905665      train_acc = 66.5 %      validation_acc = 65.7 %\n",
      "Epoch = 39     train_loss = 0.893567      train_acc = 69.5 %      validation_acc = 66.42 %\n",
      "Epoch = 40     train_loss = 0.895101      train_acc = 68.5 %      validation_acc = 66.98 %\n",
      "Epoch = 41     train_loss = 0.903912      train_acc = 68.0 %      validation_acc = 66.54 %\n",
      "Epoch = 42     train_loss = 0.893778      train_acc = 67.5 %      validation_acc = 67.38 %\n",
      "Epoch = 43     train_loss = 0.869441      train_acc = 67.5 %      validation_acc = 67.64 %\n",
      "Epoch = 44     train_loss = 0.854324      train_acc = 71.0 %      validation_acc = 67.84 %\n",
      "Epoch = 45     train_loss = 0.849889      train_acc = 70.0 %      validation_acc = 67.52 %\n",
      "Epoch = 46     train_loss = 0.823749      train_acc = 72.5 %      validation_acc = 68.04 %\n",
      "Epoch = 47     train_loss = 0.828759      train_acc = 71.5 %      validation_acc = 68.02 %\n",
      "Epoch = 48     train_loss = 0.812283      train_acc = 71.5 %      validation_acc = 68.32 %\n",
      "Epoch = 49     train_loss = 0.826927      train_acc = 71.5 %      validation_acc = 68.0 %\n",
      "Epoch = 50     train_loss = 0.81492      train_acc = 72.5 %      validation_acc = 67.56 %\n",
      "Epoch = 51     train_loss = 0.808516      train_acc = 73.0 %      validation_acc = 68.3 %\n",
      "Epoch = 52     train_loss = 0.800742      train_acc = 73.0 %      validation_acc = 68.74 %\n",
      "Epoch = 53     train_loss = 0.789253      train_acc = 72.5 %      validation_acc = 68.78 %\n",
      "Epoch = 54     train_loss = 0.770149      train_acc = 71.5 %      validation_acc = 69.42 %\n",
      "Epoch = 55     train_loss = 0.800349      train_acc = 71.0 %      validation_acc = 69.0 %\n",
      "Epoch = 56     train_loss = 0.769704      train_acc = 73.5 %      validation_acc = 69.46 %\n",
      "Epoch = 57     train_loss = 0.787183      train_acc = 72.0 %      validation_acc = 68.48 %\n",
      "Epoch = 58     train_loss = 0.775709      train_acc = 71.0 %      validation_acc = 68.86 %\n",
      "Epoch = 59     train_loss = 0.746095      train_acc = 74.5 %      validation_acc = 69.16 %\n",
      "Epoch = 60     train_loss = 0.748642      train_acc = 72.0 %      validation_acc = 68.78 %\n",
      "Epoch = 61     train_loss = 0.726056      train_acc = 72.5 %      validation_acc = 68.46 %\n",
      "Epoch = 62     train_loss = 0.729964      train_acc = 73.0 %      validation_acc = 69.32 %\n",
      "Epoch = 63     train_loss = 0.767735      train_acc = 70.0 %      validation_acc = 68.28 %\n",
      "Epoch = 64     train_loss = 0.7456      train_acc = 71.5 %      validation_acc = 69.5 %\n",
      "Epoch = 65     train_loss = 0.731368      train_acc = 72.5 %      validation_acc = 69.4 %\n",
      "Epoch = 66     train_loss = 0.718256      train_acc = 73.0 %      validation_acc = 69.7 %\n",
      "Epoch = 67     train_loss = 0.735746      train_acc = 73.0 %      validation_acc = 68.88 %\n",
      "Epoch = 68     train_loss = 0.728106      train_acc = 71.5 %      validation_acc = 68.9 %\n",
      "Epoch = 69     train_loss = 0.707652      train_acc = 73.5 %      validation_acc = 69.34 %\n",
      "Epoch = 70     train_loss = 0.717306      train_acc = 73.0 %      validation_acc = 69.18 %\n",
      "Epoch = 71     train_loss = 0.700738      train_acc = 75.5 %      validation_acc = 69.28 %\n",
      "Epoch = 72     train_loss = 0.722602      train_acc = 74.0 %      validation_acc = 68.64 %\n",
      "Epoch = 73     train_loss = 0.741728      train_acc = 72.5 %      validation_acc = 68.46 %\n",
      "Epoch = 74     train_loss = 0.671728      train_acc = 77.0 %      validation_acc = 69.24 %\n",
      "Epoch = 75     train_loss = 0.695079      train_acc = 76.5 %      validation_acc = 69.2 %\n",
      "Epoch = 76     train_loss = 0.705137      train_acc = 76.0 %      validation_acc = 68.48 %\n",
      "Epoch = 77     train_loss = 0.677923      train_acc = 77.0 %      validation_acc = 68.68 %\n",
      "Epoch = 78     train_loss = 0.685194      train_acc = 76.5 %      validation_acc = 68.98 %\n",
      "Epoch = 79     train_loss = 0.636519      train_acc = 78.0 %      validation_acc = 69.5 %\n",
      "Epoch = 80     train_loss = 0.708675      train_acc = 74.0 %      validation_acc = 67.84 %\n",
      "Epoch = 81     train_loss = 0.670292      train_acc = 77.5 %      validation_acc = 69.44 %\n",
      "Epoch = 82     train_loss = 0.692787      train_acc = 77.5 %      validation_acc = 68.72 %\n",
      "Epoch = 83     train_loss = 0.68928      train_acc = 78.0 %      validation_acc = 68.46 %\n",
      "Epoch = 84     train_loss = 0.659371      train_acc = 77.5 %      validation_acc = 69.0 %\n",
      "Epoch = 85     train_loss = 0.639098      train_acc = 77.5 %      validation_acc = 69.82 %\n",
      "Epoch = 86     train_loss = 0.683105      train_acc = 78.0 %      validation_acc = 69.0 %\n",
      "Epoch = 87     train_loss = 0.697667      train_acc = 75.5 %      validation_acc = 68.14 %\n",
      "Epoch = 88     train_loss = 0.662525      train_acc = 78.5 %      validation_acc = 68.52 %\n",
      "Epoch = 89     train_loss = 0.651589      train_acc = 78.5 %      validation_acc = 69.22 %\n",
      "Epoch = 90     train_loss = 0.632021      train_acc = 78.5 %      validation_acc = 69.62 %\n",
      "Epoch = 91     train_loss = 0.623986      train_acc = 79.5 %      validation_acc = 69.52 %\n",
      "Epoch = 92     train_loss = 0.634439      train_acc = 78.5 %      validation_acc = 69.58 %\n",
      "Epoch = 93     train_loss = 0.631113      train_acc = 81.0 %      validation_acc = 69.72 %\n",
      "Epoch = 94     train_loss = 0.646495      train_acc = 79.0 %      validation_acc = 69.36 %\n",
      "Epoch = 95     train_loss = 0.630542      train_acc = 80.0 %      validation_acc = 69.5 %\n",
      "Epoch = 96     train_loss = 0.660325      train_acc = 76.0 %      validation_acc = 68.96 %\n",
      "Epoch = 97     train_loss = 0.657837      train_acc = 79.0 %      validation_acc = 69.44 %\n",
      "Epoch = 98     train_loss = 0.608807      train_acc = 80.0 %      validation_acc = 69.72 %\n",
      "Epoch = 99     train_loss = 0.619752      train_acc = 79.0 %      validation_acc = 70.04 %\n"
     ]
    }
   ],
   "source": [
    "history = {}\n",
    "history['acc'] = []\n",
    "history['val_acc'] = []\n",
    "with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as session:\n",
    "    # 可视化整个网络结构的视图，通过 TensorBoard 查看\n",
    "    tf.summary.FileWriter('./graphs', session.graph)\n",
    "    session.run(tf.global_variables_initializer())\n",
    "    for i in range(epoch):\n",
    "        # 将训练集按 batch_size 切分为很多 batch，每个 batch 用于更新一次模型参数\n",
    "        for X_batch, Y_batch in get_batch(X_train, Y_train, batch_size):\n",
    "            session.run(optimizer, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:dropout})\n",
    "        \n",
    "        # 本轮训练集（45000张图片）最后一个 batch 的损失值\n",
    "        loss = session.run(cost, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:1})\n",
    "        \n",
    "        # 本轮训练后的模型用于训练集的最后一个 batch 的准确率\n",
    "        acc = session.run(accuracy, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:1})\n",
    "        history['acc'].append(acc)\n",
    "        \n",
    "        # 本轮训练后的模型用于验证集（5000张图片）的准确率\n",
    "        val_acc = session.run(accuracy, feed_dict={x_input:X_test, y_true:Y_test, keep_prob:1})\n",
    "        history['val_acc'].append(val_acc)\n",
    "        \n",
    "        print(\"Epoch =\", i, \"    train_loss =\", loss, \n",
    "              \"     train_acc =\", round(acc * 100, 2), \"%\", \n",
    "              \"     validation_acc =\", round(val_acc * 100, 2), \"%\")\n",
    "\n",
    "    saver = tf.train.Saver()\n",
    "    save_path = saver.save(session, '.\\michael')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 可以看到，采用三层卷积加池化的模型，可以在训练100代后达到将近 70% 的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nIiIiIhKA/h8PcQB3nI1ywwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2ed4cfc2828>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 5))\n",
    "plt.plot(range(100), history['acc'], label='Train Accuracy')\n",
    "plt.plot(range(100), history['val_acc'], label='Test Accuracy')\n",
    "plt.title('Model 1, Vanilla CNN Model', size=15)\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.legend()\n",
    "plt.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 修改模型\n",
    "\n",
    "下面使用 TensorFlow 所提供的封装好的各层函数重新实现同样结构的模型。\n",
    "\n",
    "不同的是这里使用 Xavier 方式初始化权重矩阵，L2正则，以及 Batch Norm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def create_model2(x, keep_prob):\n",
    "    x = tf.contrib.layers.conv2d(x, 16, 3, 1, 'SAME', activation_fn=None, weights_regularizer=tf.contrib.layers.l2_regularizer(0.1))\n",
    "    x = tf.contrib.layers.batch_norm(x)\n",
    "    x = tf.nn.relu(x)\n",
    "    x = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], 'VALID')\n",
    "    x = tf.contrib.layers.conv2d(x, 16, 3, 1, 'SAME', activation_fn=None, weights_regularizer=tf.contrib.layers.l2_regularizer(0.1))\n",
    "    x = tf.contrib.layers.batch_norm(x)\n",
    "    x = tf.nn.relu(x)\n",
    "    x = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], 'VALID')\n",
    "    x = tf.contrib.layers.conv2d(x, 16, 3, 1, 'SAME', activation_fn=None, weights_regularizer=tf.contrib.layers.l2_regularizer(0.1))\n",
    "    x = tf.contrib.layers.batch_norm(x)\n",
    "    x = tf.nn.relu(x)\n",
    "    x = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], 'VALID')\n",
    "    x = tf.contrib.layers.flatten(x)\n",
    "    x = tf.contrib.layers.fully_connected(x, 128, activation_fn=tf.nn.relu)\n",
    "    x = tf.nn.dropout(x, keep_prob)\n",
    "    x = tf.contrib.layers.fully_connected(x, 10, activation_fn=None)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch = 0     train_loss = 1.44383      train_acc = 49.0 %      validation_acc = 47.04 %\n",
      "Epoch = 1     train_loss = 1.28605      train_acc = 53.0 %      validation_acc = 54.46 %\n",
      "Epoch = 2     train_loss = 1.19024      train_acc = 58.5 %      validation_acc = 58.68 %\n",
      "Epoch = 3     train_loss = 1.09683      train_acc = 61.5 %      validation_acc = 61.14 %\n",
      "Epoch = 4     train_loss = 1.0339      train_acc = 62.0 %      validation_acc = 63.14 %\n",
      "Epoch = 5     train_loss = 1.01964      train_acc = 62.0 %      validation_acc = 64.12 %\n",
      "Epoch = 6     train_loss = 0.978913      train_acc = 64.0 %      validation_acc = 65.3 %\n",
      "Epoch = 7     train_loss = 0.959868      train_acc = 66.5 %      validation_acc = 65.76 %\n",
      "Epoch = 8     train_loss = 0.923282      train_acc = 66.5 %      validation_acc = 66.36 %\n",
      "Epoch = 9     train_loss = 0.898329      train_acc = 65.5 %      validation_acc = 66.88 %\n",
      "Epoch = 10     train_loss = 0.933799      train_acc = 65.5 %      validation_acc = 66.5 %\n",
      "Epoch = 11     train_loss = 0.883114      train_acc = 68.0 %      validation_acc = 68.18 %\n",
      "Epoch = 12     train_loss = 0.888959      train_acc = 69.0 %      validation_acc = 68.7 %\n",
      "Epoch = 13     train_loss = 0.857722      train_acc = 69.0 %      validation_acc = 68.92 %\n",
      "Epoch = 14     train_loss = 0.853187      train_acc = 70.0 %      validation_acc = 69.44 %\n",
      "Epoch = 15     train_loss = 0.821683      train_acc = 69.5 %      validation_acc = 69.86 %\n",
      "Epoch = 16     train_loss = 0.816599      train_acc = 69.0 %      validation_acc = 70.5 %\n",
      "Epoch = 17     train_loss = 0.816942      train_acc = 71.5 %      validation_acc = 70.42 %\n",
      "Epoch = 18     train_loss = 0.807819      train_acc = 71.0 %      validation_acc = 71.02 %\n",
      "Epoch = 19     train_loss = 0.814943      train_acc = 69.5 %      validation_acc = 71.2 %\n",
      "Epoch = 20     train_loss = 0.807089      train_acc = 70.5 %      validation_acc = 71.32 %\n",
      "Epoch = 21     train_loss = 0.792852      train_acc = 70.5 %      validation_acc = 71.24 %\n",
      "Epoch = 22     train_loss = 0.783539      train_acc = 70.5 %      validation_acc = 71.98 %\n",
      "Epoch = 23     train_loss = 0.772413      train_acc = 72.0 %      validation_acc = 71.92 %\n",
      "Epoch = 24     train_loss = 0.750191      train_acc = 73.0 %      validation_acc = 71.92 %\n",
      "Epoch = 25     train_loss = 0.754239      train_acc = 73.0 %      validation_acc = 71.98 %\n",
      "Epoch = 26     train_loss = 0.756466      train_acc = 72.5 %      validation_acc = 71.44 %\n",
      "Epoch = 27     train_loss = 0.741755      train_acc = 73.5 %      validation_acc = 71.3 %\n",
      "Epoch = 28     train_loss = 0.75193      train_acc = 71.5 %      validation_acc = 71.22 %\n",
      "Epoch = 29     train_loss = 0.746432      train_acc = 72.0 %      validation_acc = 71.2 %\n",
      "Epoch = 30     train_loss = 0.719729      train_acc = 75.5 %      validation_acc = 71.98 %\n",
      "Epoch = 31     train_loss = 0.703946      train_acc = 76.5 %      validation_acc = 71.32 %\n",
      "Epoch = 32     train_loss = 0.687897      train_acc = 76.0 %      validation_acc = 71.48 %\n",
      "Epoch = 33     train_loss = 0.68697      train_acc = 75.5 %      validation_acc = 71.88 %\n",
      "Epoch = 34     train_loss = 0.684019      train_acc = 76.5 %      validation_acc = 72.18 %\n",
      "Epoch = 35     train_loss = 0.665536      train_acc = 75.5 %      validation_acc = 71.9 %\n",
      "Epoch = 36     train_loss = 0.674682      train_acc = 75.5 %      validation_acc = 71.78 %\n",
      "Epoch = 37     train_loss = 0.659808      train_acc = 77.0 %      validation_acc = 72.14 %\n",
      "Epoch = 38     train_loss = 0.674418      train_acc = 78.0 %      validation_acc = 72.52 %\n",
      "Epoch = 39     train_loss = 0.642749      train_acc = 76.5 %      validation_acc = 72.16 %\n",
      "Epoch = 40     train_loss = 0.64276      train_acc = 77.5 %      validation_acc = 72.14 %\n",
      "Epoch = 41     train_loss = 0.638699      train_acc = 78.0 %      validation_acc = 71.9 %\n",
      "Epoch = 42     train_loss = 0.640185      train_acc = 78.5 %      validation_acc = 72.54 %\n",
      "Epoch = 43     train_loss = 0.62204      train_acc = 78.5 %      validation_acc = 72.38 %\n",
      "Epoch = 44     train_loss = 0.641657      train_acc = 75.5 %      validation_acc = 72.44 %\n",
      "Epoch = 45     train_loss = 0.609693      train_acc = 78.0 %      validation_acc = 72.22 %\n",
      "Epoch = 46     train_loss = 0.604402      train_acc = 78.5 %      validation_acc = 72.56 %\n",
      "Epoch = 47     train_loss = 0.603652      train_acc = 78.0 %      validation_acc = 73.08 %\n",
      "Epoch = 48     train_loss = 0.594098      train_acc = 79.0 %      validation_acc = 72.26 %\n",
      "Epoch = 49     train_loss = 0.59931      train_acc = 79.5 %      validation_acc = 72.2 %\n",
      "Epoch = 50     train_loss = 0.592611      train_acc = 77.5 %      validation_acc = 72.26 %\n",
      "Epoch = 51     train_loss = 0.602889      train_acc = 77.5 %      validation_acc = 72.46 %\n",
      "Epoch = 52     train_loss = 0.567751      train_acc = 78.0 %      validation_acc = 72.68 %\n",
      "Epoch = 53     train_loss = 0.58264      train_acc = 79.5 %      validation_acc = 72.58 %\n",
      "Epoch = 54     train_loss = 0.583094      train_acc = 78.5 %      validation_acc = 72.42 %\n",
      "Epoch = 55     train_loss = 0.585063      train_acc = 78.0 %      validation_acc = 72.38 %\n",
      "Epoch = 56     train_loss = 0.609397      train_acc = 78.5 %      validation_acc = 72.06 %\n",
      "Epoch = 57     train_loss = 0.573951      train_acc = 80.5 %      validation_acc = 73.0 %\n",
      "Epoch = 58     train_loss = 0.561742      train_acc = 80.0 %      validation_acc = 72.74 %\n",
      "Epoch = 59     train_loss = 0.547654      train_acc = 82.5 %      validation_acc = 72.18 %\n",
      "Epoch = 60     train_loss = 0.571219      train_acc = 79.5 %      validation_acc = 72.24 %\n",
      "Epoch = 61     train_loss = 0.548337      train_acc = 81.0 %      validation_acc = 72.48 %\n",
      "Epoch = 62     train_loss = 0.540835      train_acc = 82.5 %      validation_acc = 72.64 %\n",
      "Epoch = 63     train_loss = 0.542076      train_acc = 82.5 %      validation_acc = 72.6 %\n",
      "Epoch = 64     train_loss = 0.527143      train_acc = 83.0 %      validation_acc = 72.3 %\n",
      "Epoch = 65     train_loss = 0.528087      train_acc = 82.0 %      validation_acc = 72.4 %\n",
      "Epoch = 66     train_loss = 0.533787      train_acc = 82.5 %      validation_acc = 72.46 %\n",
      "Epoch = 67     train_loss = 0.516495      train_acc = 83.0 %      validation_acc = 72.22 %\n",
      "Epoch = 68     train_loss = 0.528279      train_acc = 81.5 %      validation_acc = 72.04 %\n",
      "Epoch = 69     train_loss = 0.525802      train_acc = 82.0 %      validation_acc = 72.26 %\n",
      "Epoch = 70     train_loss = 0.529881      train_acc = 83.0 %      validation_acc = 71.92 %\n",
      "Epoch = 71     train_loss = 0.520428      train_acc = 82.0 %      validation_acc = 72.9 %\n",
      "Epoch = 72     train_loss = 0.531525      train_acc = 82.0 %      validation_acc = 72.52 %\n",
      "Epoch = 73     train_loss = 0.519694      train_acc = 83.0 %      validation_acc = 71.76 %\n",
      "Epoch = 74     train_loss = 0.499883      train_acc = 84.0 %      validation_acc = 72.54 %\n",
      "Epoch = 75     train_loss = 0.515057      train_acc = 81.5 %      validation_acc = 72.48 %\n",
      "Epoch = 76     train_loss = 0.524902      train_acc = 83.5 %      validation_acc = 72.3 %\n",
      "Epoch = 77     train_loss = 0.4929      train_acc = 85.0 %      validation_acc = 72.2 %\n",
      "Epoch = 78     train_loss = 0.497353      train_acc = 84.5 %      validation_acc = 71.62 %\n",
      "Epoch = 79     train_loss = 0.484535      train_acc = 81.5 %      validation_acc = 72.5 %\n",
      "Epoch = 80     train_loss = 0.508768      train_acc = 80.5 %      validation_acc = 72.36 %\n",
      "Epoch = 81     train_loss = 0.490297      train_acc = 83.0 %      validation_acc = 71.8 %\n",
      "Epoch = 82     train_loss = 0.467212      train_acc = 83.5 %      validation_acc = 72.24 %\n",
      "Epoch = 83     train_loss = 0.480988      train_acc = 83.0 %      validation_acc = 72.14 %\n",
      "Epoch = 84     train_loss = 0.496892      train_acc = 85.5 %      validation_acc = 72.6 %\n",
      "Epoch = 85     train_loss = 0.482231      train_acc = 83.5 %      validation_acc = 72.64 %\n",
      "Epoch = 86     train_loss = 0.47109      train_acc = 85.5 %      validation_acc = 72.68 %\n",
      "Epoch = 87     train_loss = 0.465077      train_acc = 85.0 %      validation_acc = 72.54 %\n",
      "Epoch = 88     train_loss = 0.47603      train_acc = 84.5 %      validation_acc = 72.24 %\n",
      "Epoch = 89     train_loss = 0.469542      train_acc = 82.5 %      validation_acc = 72.46 %\n",
      "Epoch = 90     train_loss = 0.45635      train_acc = 84.0 %      validation_acc = 72.58 %\n",
      "Epoch = 91     train_loss = 0.465965      train_acc = 83.0 %      validation_acc = 72.58 %\n",
      "Epoch = 92     train_loss = 0.466201      train_acc = 85.0 %      validation_acc = 72.1 %\n",
      "Epoch = 93     train_loss = 0.45872      train_acc = 84.0 %      validation_acc = 71.86 %\n",
      "Epoch = 94     train_loss = 0.450225      train_acc = 84.0 %      validation_acc = 72.32 %\n",
      "Epoch = 95     train_loss = 0.446824      train_acc = 86.5 %      validation_acc = 72.62 %\n",
      "Epoch = 96     train_loss = 0.445738      train_acc = 86.0 %      validation_acc = 72.46 %\n",
      "Epoch = 97     train_loss = 0.460024      train_acc = 83.5 %      validation_acc = 72.8 %\n",
      "Epoch = 98     train_loss = 0.460505      train_acc = 83.0 %      validation_acc = 72.8 %\n",
      "Epoch = 99     train_loss = 0.455537      train_acc = 84.0 %      validation_acc = 72.68 %\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "x_input   = tf.placeholder(tf.float32, shape=(None, 32, 32, 3), name='x_input')\n",
    "y_true    = tf.placeholder(tf.float32, shape=(None, n_class), name='y_true')\n",
    "keep_prob = tf.placeholder(tf.float32, name='keep_prob')\n",
    "\n",
    "y_pred = create_model2(x_input, keep_prob)\n",
    "cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_pred, labels=y_true))\n",
    "optimizer = tf.train.AdamOptimizer().minimize(cost)\n",
    "correct_pred = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_true, 1))    \n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name='accuracy')\n",
    "\n",
    "history2 = {}\n",
    "history2['acc'] = []\n",
    "history2['val_acc'] = []\n",
    "with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as session:\n",
    "    # 可视化整个网络结构的视图，通过 TensorBoard 查看\n",
    "    tf.summary.FileWriter('./graphs', session.graph)\n",
    "    session.run(tf.global_variables_initializer())\n",
    "    for i in range(epoch):\n",
    "        # 将训练集按 batch_size 切分为很多 batch，每个 batch 用于更新一次模型参数\n",
    "        for X_batch, Y_batch in get_batch(X_train, Y_train, batch_size):\n",
    "            session.run(optimizer, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:dropout})\n",
    "        \n",
    "        # 本轮训练集（45000张图片）最后一个 batch 的损失值\n",
    "        loss = session.run(cost, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:1})\n",
    "        \n",
    "        # 本轮训练后的模型用于训练集的最后一个 batch 的准确率\n",
    "        acc = session.run(accuracy, feed_dict={x_input:X_batch, y_true:Y_batch, keep_prob:1})\n",
    "        history2['acc'].append(acc)\n",
    "        \n",
    "        # 本轮训练后的模型用于验证集（5000张图片）的准确率\n",
    "        val_acc = session.run(accuracy, feed_dict={x_input:X_test, y_true:Y_test, keep_prob:1})\n",
    "        history2['val_acc'].append(val_acc)\n",
    "        \n",
    "        print(\"Epoch =\", i, \"    train_loss =\", loss, \n",
    "              \"     train_acc =\", round(acc * 100, 2), \"%\", \n",
    "              \"     validation_acc =\", round(val_acc * 100, 2), \"%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 可以看到，对于同样的模型结构，新模型可以在100代训练后达到72%的准确率。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 总结：模型性能对比"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nWvHayghWhscW7lvf2ZFXbu7GhH6tSc/K4+vtp1i9P7awshebcpEj5y5wh8UCv1UpyO/SJC0XsnK5\nkJXLoI7ShVOIumrXySSe+z6c/u0bs+CBvjzw5S4+WB/FHb39Chci/2jjMd7/7SihzR15/4EhNPVw\nKTXOwZ2a8smm42w/nsj1XY1u6b9FniM7N59Rdq5hV5Kbg1rw5ZaTrD98vnCbb0NXvpzUhyGd7e/m\nLkRdJJU9IcRV6WBMCgkXshnUsUmpLVQXs/P4cd9ZRgT40NjduJnZeCSeTUfieXFUV6L/usiSXWfI\nzcsv8kR718kkvOo78+eLw4ssTWCte0tPljwYWuL7nvUdGNihCSvDY3n2RmNSlU1HqnfMXCtvNxrV\ndybsTDJn/7qIk4Oif4fG1XJsIUT1iv4rgwe/2oNfo/rMndALZ0cHXhjVlZve28wH66P41+gA1hyM\n479rDjMmqAW3+yaXWdEDCPFvhJuzIxuPxBdW9laFx+LT0IXepYwHtIersyOrp197WXEIUVfJbJxC\niKvSCz8c4L75O5k4fyfH4y/YDJOfr3li2T6e+34/183eyFfbTpKdm8/MVZG09q7PvaFtCGrlycWc\nPKKs4th18i9C2niXWtGz102BzTmbfLGwBXHTkQR8GrrQuYx1pSqLUooefl6ER6ew6Wg8vVo3omE5\nJqQRQtQer6yIICsnj8/uCylsxevi25CxvVuxcNtJft4fy+NL9tGjpWeZSylYcnFy5Jp23oUPqwq6\ncN7YvXmlXCeFELZJZU8IcdXJzcsnMjaVwJae7DudzA3vbuKtXw6RkV106u531x1h9f44pg5qR0Dz\nhvzrp4MM+s/vHD6XxjMju+Di5FjYxTHcYmmC82mZnEhIp2/by3taXWBEgC/OjopV+2PJy9f8EZXA\noI5Nq3XMXJCfJ0fOpXHgbCqDOjWptuMKIUp2ISuX3yLPkZuXX2bYP0//xfm0zFLDbD+eyNqIczwy\ntAPtLdbVBHhiRCecHBx4+H9/0tDVmU8nhuDqXHzCk9IM7tSUk4kZnE7MKOzCOfoyu3AKIUonlT0h\nxFXnZGI6Wbn53Nffn/VPDuHmoJZ8tOEY18/eyKrwWLTW/LTvLO+vj+LOED+eu7EL3/y9Hx/c1RON\n5pp23twUaKxf59+4AR6uTuyzWJpg14m/AIrNSFdRnvWdGdihCavCY411oC7mVPuyB0GtvMjXxv8H\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2f1ecafd978>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 5))\n",
    "plt.subplot(121)\n",
    "plt.plot(range(100), history['acc'], label='Train Accuracy')\n",
    "plt.plot(range(100), history['val_acc'], label='Test Accuracy')\n",
    "plt.title('Model 1, Vanilla CNN Model', size=15)\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.ylim([0.3, 0.95])\n",
    "plt.legend()\n",
    "plt.grid(True)\n",
    "plt.subplot(122)\n",
    "plt.plot(range(100), history2['acc'], label='Train Accuracy')\n",
    "plt.plot(range(100), history2['val_acc'], label='Test Accuracy')\n",
    "plt.title('Model 2, CNN Model with Xavier / BN / L2', size=15)\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.ylim([0.3, 0.95])\n",
    "plt.legend()\n",
    "plt.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对比两个模型在相同条件下训练准确度和测试准确度的爬升情况，有以下分析：\n",
    "\n",
    "- **Model#2的收敛速度要远远快于Model#1**：Model#1用了25代训练才抵达60%的测试准确率，而Model#2只用了4代就达到了(曲线弧度更陡)。\n",
    "- **Model#2的绝对性能要稍好于Model#1**：同样经过100代训练，Model#2的测试准确率比Model#1提升了2%左右。\n",
    "\n",
    "以上的提升来自于权重初始化方式的改变（从截断正态分布到Xavier初始化）、Batch Normalization 和 L2 Regularization 的引入。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Couple of tips:\n",
    "- make sure you do Xavier initialization (check that you use the correct parameters depending upon your activation function);\n",
    "- make sure you are using ReLU (but try Leaky ReLU as well) as your activation function - or possibly ELU;\n",
    "- implement batch normalization prior to fully connected layers (its often useful in other layers);\n",
    "- make sure you've implemented dropout;\n",
    "- test out a different regularization and dropout parameters;\n",
    "- building an ensemble might net you an additional 1-2% (do this at the end)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
